﻿
// SpiritDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "Spirit.h"
#include "SpiritDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CSpiritDlg 对话框



CSpiritDlg::CSpiritDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_SPIRIT_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSpiritDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CSpiritDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_NCHITTEST()
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CSpiritDlg 消息处理程序

BOOL CSpiritDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	//加载精灵图片
	for (int i = 0; i < 24; i++)
	{
		m_spiritBmp[i].LoadBitmap(IDB_BITMAP1 + i);//加载精灵图片
	}
	BITMAP logmap;
	m_spiritBmp[0].GetBitmap(&logmap);//获取图片信息
	CDC memDC;
	memDC.CreateCompatibleDC(NULL);//创建一个内存DC
	memDC.SelectObject(&m_spiritBmp[0]);//将精灵图片选入内存DC

	CRgn rgn;//创建一个区域
	rgn.CreateRectRgn(0, 0, logmap.bmWidth, logmap.bmHeight);//设置区域大小
	//把精灵图片白色的地方扣掉
	for (int i = 0; i < logmap.bmWidth; i++)
		for (int j = 0; j < logmap.bmHeight; j++)
		{
			CRgn rgn1;
			rgn1.CreateRectRgn(i, j, i + 1, j + 1);
			auto color = memDC.GetPixel(i, j);
			int a = abs(GetRValue(color) - 248);
			int b = abs(GetGValue(color) - 248);
			int c = abs(GetBValue(color) - 248);
			if (a <= 7 && b <= 7 && c <= 15)
				rgn.CombineRgn(&rgn, &rgn1, RGN_XOR);//将白色区域从区域中扣掉
		}
	SetWindowRgn(rgn, TRUE);//将区域设置到窗口中

	SetTimer(0, 200, NULL);//设置定时器
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CSpiritDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this); // 用于绘制的设备上下文
		BITMAP logmap;
		m_spiritBmp[m_spiritIndex].GetBitmap(&logmap);//获取图片信息
		CDC memDC;
		memDC.CreateCompatibleDC(NULL);//创建一个内存DC
		memDC.SelectObject(&m_spiritBmp[m_spiritIndex]);//将精灵图片选入内存DC
		dc.BitBlt(0, 0, logmap.bmWidth, logmap.bmHeight, &memDC, 0, 0, SRCCOPY);//将精灵图片复制到屏幕DC
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSpiritDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



LRESULT CSpiritDlg::OnNcHitTest(CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	LRESULT result = CDialogEx::OnNcHitTest(point);//调用默认处理
	if (result == HTCLIENT)//如果光标在客户区
		result = HTCAPTION;//改变光标为移动光标

	return result;//返回光标类型
}


void CSpiritDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nIDEvent)
	{
	case 0:
	{
		CDC memDC;
		memDC.CreateCompatibleDC(NULL);//创建一个内存DC
		memDC.SelectObject(&m_spiritBmp[m_spiritIndex]);//将精灵图片选入内存DC

		BITMAP logmap;
		m_spiritBmp[m_spiritIndex].GetBitmap(&logmap);//获取图片信息
		CRgn rgn;//创建一个区域
		rgn.CreateRectRgn(0, 0, logmap.bmWidth, logmap.bmHeight);//设置区域大小
		//把精灵图片白色的地方扣掉
		for (int i = 0; i < logmap.bmWidth; i++)
			for (int j = 0; j < logmap.bmHeight; j++)
			{
				CRgn rgn1;
				rgn1.CreateRectRgn(i, j, i + 1, j + 1);
				auto color = memDC.GetPixel(i, j);
				int a = abs(GetRValue(color) - 248);
				int b = abs(GetGValue(color) - 248);
				int c = abs(GetBValue(color) - 248);
				if (a <= 7 && b <= 7 && c <= 15)
					rgn.CombineRgn(&rgn, &rgn1, RGN_XOR);//将白色区域从区域中扣掉
			}
		SetWindowRgn(rgn, TRUE);//将区域设置到窗口中
		m_spiritIndex = m_spiritIndex++ % 24;//循环播放精灵图片
		Invalidate(TRUE);//刷新窗口
	}
	break;
	}
	CDialogEx::OnTimer(nIDEvent);
}
